1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.primitives;
18  
19  import com.google.common.annotations.GwtCompatible;
20  import com.google.common.collect.testing.Helpers;
21  
22  import junit.framework.TestCase;
23  
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.Collections;
27  import java.util.Comparator;
28  import java.util.List;
29  
30  /**
31   * Unit test for {@link Chars}.
32   *
33   * @author Kevin Bourrillion
34   */
35  @GwtCompatible(emulated = true)
36  @SuppressWarnings("cast") // redundant casts are intentional and harmless
37  public class CharsTest extends TestCase {
38    private static final char[] EMPTY = {};
39    private static final char[] ARRAY1 = {(char) 1};
40    private static final char[] ARRAY234
41        = {(char) 2, (char) 3, (char) 4};
42  
43    private static final char LEAST = Character.MIN_VALUE;
44    private static final char GREATEST = Character.MAX_VALUE;
45  
46    private static final char[] VALUES =
47        {LEAST, 'a', '\u00e0', '\udcaa', GREATEST};
48  
49    public void testHashCode() {
50      for (char value : VALUES) {
51        assertEquals(((Character) value).hashCode(), Chars.hashCode(value));
52      }
53    }
54  
55    public void testCheckedCast() {
56      for (char value : VALUES) {
57        assertEquals(value, Chars.checkedCast((long) value));
58      }
59      assertCastFails(GREATEST + 1L);
60      assertCastFails(LEAST - 1L);
61      assertCastFails(Long.MAX_VALUE);
62      assertCastFails(Long.MIN_VALUE);
63    }
64  
65    public void testSaturatedCast() {
66      for (char value : VALUES) {
67        assertEquals(value, Chars.saturatedCast((long) value));
68      }
69      assertEquals(GREATEST, Chars.saturatedCast(GREATEST + 1L));
70      assertEquals(LEAST, Chars.saturatedCast(LEAST - 1L));
71      assertEquals(GREATEST, Chars.saturatedCast(Long.MAX_VALUE));
72      assertEquals(LEAST, Chars.saturatedCast(Long.MIN_VALUE));
73    }
74  
75    private void assertCastFails(long value) {
76      try {
77        Chars.checkedCast(value);
78        fail("Cast to char should have failed: " + value);
79      } catch (IllegalArgumentException ex) {
80        assertTrue(value + " not found in exception text: " + ex.getMessage(),
81            ex.getMessage().contains(String.valueOf(value)));
82      }
83    }
84  
85    public void testCompare() {
86      for (char x : VALUES) {
87        for (char y : VALUES) {
88          // note: spec requires only that the sign is the same
89          assertEquals(x + ", " + y,
90                       Character.valueOf(x).compareTo(y),
91                       Chars.compare(x, y));
92        }
93      }
94    }
95  
96    public void testContains() {
97      assertFalse(Chars.contains(EMPTY, (char) 1));
98      assertFalse(Chars.contains(ARRAY1, (char) 2));
99      assertFalse(Chars.contains(ARRAY234, (char) 1));
100     assertTrue(Chars.contains(new char[] {(char) -1}, (char) -1));
101     assertTrue(Chars.contains(ARRAY234, (char) 2));
102     assertTrue(Chars.contains(ARRAY234, (char) 3));
103     assertTrue(Chars.contains(ARRAY234, (char) 4));
104   }
105 
106   public void testIndexOf() {
107     assertEquals(-1, Chars.indexOf(EMPTY, (char) 1));
108     assertEquals(-1, Chars.indexOf(ARRAY1, (char) 2));
109     assertEquals(-1, Chars.indexOf(ARRAY234, (char) 1));
110     assertEquals(0, Chars.indexOf(
111         new char[] {(char) -1}, (char) -1));
112     assertEquals(0, Chars.indexOf(ARRAY234, (char) 2));
113     assertEquals(1, Chars.indexOf(ARRAY234, (char) 3));
114     assertEquals(2, Chars.indexOf(ARRAY234, (char) 4));
115     assertEquals(1, Chars.indexOf(
116         new char[] { (char) 2, (char) 3, (char) 2, (char) 3 },
117         (char) 3));
118   }
119 
120   public void testIndexOf_arrayTarget() {
121     assertEquals(0, Chars.indexOf(EMPTY, EMPTY));
122     assertEquals(0, Chars.indexOf(ARRAY234, EMPTY));
123     assertEquals(-1, Chars.indexOf(EMPTY, ARRAY234));
124     assertEquals(-1, Chars.indexOf(ARRAY234, ARRAY1));
125     assertEquals(-1, Chars.indexOf(ARRAY1, ARRAY234));
126     assertEquals(0, Chars.indexOf(ARRAY1, ARRAY1));
127     assertEquals(0, Chars.indexOf(ARRAY234, ARRAY234));
128     assertEquals(0, Chars.indexOf(
129         ARRAY234, new char[] { (char) 2, (char) 3 }));
130     assertEquals(1, Chars.indexOf(
131         ARRAY234, new char[] { (char) 3, (char) 4 }));
132     assertEquals(1, Chars.indexOf(ARRAY234, new char[] { (char) 3 }));
133     assertEquals(2, Chars.indexOf(ARRAY234, new char[] { (char) 4 }));
134     assertEquals(1, Chars.indexOf(new char[] { (char) 2, (char) 3,
135         (char) 3, (char) 3, (char) 3 },
136         new char[] { (char) 3 }
137     ));
138     assertEquals(2, Chars.indexOf(
139         new char[] { (char) 2, (char) 3, (char) 2,
140             (char) 3, (char) 4, (char) 2, (char) 3},
141         new char[] { (char) 2, (char) 3, (char) 4}
142     ));
143     assertEquals(1, Chars.indexOf(
144         new char[] { (char) 2, (char) 2, (char) 3,
145             (char) 4, (char) 2, (char) 3, (char) 4},
146         new char[] { (char) 2, (char) 3, (char) 4}
147     ));
148     assertEquals(-1, Chars.indexOf(
149         new char[] { (char) 4, (char) 3, (char) 2},
150         new char[] { (char) 2, (char) 3, (char) 4}
151     ));
152   }
153 
154   public void testLastIndexOf() {
155     assertEquals(-1, Chars.lastIndexOf(EMPTY, (char) 1));
156     assertEquals(-1, Chars.lastIndexOf(ARRAY1, (char) 2));
157     assertEquals(-1, Chars.lastIndexOf(ARRAY234, (char) 1));
158     assertEquals(0, Chars.lastIndexOf(
159         new char[] {(char) -1}, (char) -1));
160     assertEquals(0, Chars.lastIndexOf(ARRAY234, (char) 2));
161     assertEquals(1, Chars.lastIndexOf(ARRAY234, (char) 3));
162     assertEquals(2, Chars.lastIndexOf(ARRAY234, (char) 4));
163     assertEquals(3, Chars.lastIndexOf(
164         new char[] { (char) 2, (char) 3, (char) 2, (char) 3 },
165         (char) 3));
166   }
167 
168   public void testMax_noArgs() {
169     try {
170       Chars.max();
171       fail();
172     } catch (IllegalArgumentException expected) {
173     }
174   }
175 
176   public void testMax() {
177     assertEquals(LEAST, Chars.max(LEAST));
178     assertEquals(GREATEST, Chars.max(GREATEST));
179     assertEquals((char) 9, Chars.max(
180         (char) 8, (char) 6, (char) 7,
181         (char) 5, (char) 3, (char) 0, (char) 9));
182   }
183 
184   public void testMin_noArgs() {
185     try {
186       Chars.min();
187       fail();
188     } catch (IllegalArgumentException expected) {
189     }
190   }
191 
192   public void testMin() {
193     assertEquals(LEAST, Chars.min(LEAST));
194     assertEquals(GREATEST, Chars.min(GREATEST));
195     assertEquals((char) 0, Chars.min(
196         (char) 8, (char) 6, (char) 7,
197         (char) 5, (char) 3, (char) 0, (char) 9));
198   }
199 
200   public void testConcat() {
201     assertTrue(Arrays.equals(EMPTY, Chars.concat()));
202     assertTrue(Arrays.equals(EMPTY, Chars.concat(EMPTY)));
203     assertTrue(Arrays.equals(EMPTY, Chars.concat(EMPTY, EMPTY, EMPTY)));
204     assertTrue(Arrays.equals(ARRAY1, Chars.concat(ARRAY1)));
205     assertNotSame(ARRAY1, Chars.concat(ARRAY1));
206     assertTrue(Arrays.equals(ARRAY1, Chars.concat(EMPTY, ARRAY1, EMPTY)));
207     assertTrue(Arrays.equals(
208         new char[] {(char) 1, (char) 1, (char) 1},
209         Chars.concat(ARRAY1, ARRAY1, ARRAY1)));
210     assertTrue(Arrays.equals(
211         new char[] {(char) 1, (char) 2, (char) 3, (char) 4},
212         Chars.concat(ARRAY1, ARRAY234)));
213   }
214 
215   public void testEnsureCapacity() {
216     assertSame(EMPTY, Chars.ensureCapacity(EMPTY, 0, 1));
217     assertSame(ARRAY1, Chars.ensureCapacity(ARRAY1, 0, 1));
218     assertSame(ARRAY1, Chars.ensureCapacity(ARRAY1, 1, 1));
219     assertTrue(Arrays.equals(
220         new char[] {(char) 1, (char) 0, (char) 0},
221         Chars.ensureCapacity(ARRAY1, 2, 1)));
222   }
223 
224   public void testEnsureCapacity_fail() {
225     try {
226       Chars.ensureCapacity(ARRAY1, -1, 1);
227       fail();
228     } catch (IllegalArgumentException expected) {
229     }
230     try {
231       // notice that this should even fail when no growth was needed
232       Chars.ensureCapacity(ARRAY1, 1, -1);
233       fail();
234     } catch (IllegalArgumentException expected) {
235     }
236   }
237 
238   public void testJoin() {
239     assertEquals("", Chars.join(",", EMPTY));
240     assertEquals("1", Chars.join(",", '1'));
241     assertEquals("1,2", Chars.join(",", '1', '2'));
242     assertEquals("123", Chars.join("", '1', '2', '3'));
243   }
244 
245   public void testLexicographicalComparator() {
246     List<char[]> ordered = Arrays.asList(
247         new char[] {},
248         new char[] {LEAST},
249         new char[] {LEAST, LEAST},
250         new char[] {LEAST, (char) 1},
251         new char[] {(char) 1},
252         new char[] {(char) 1, LEAST},
253         new char[] {GREATEST, GREATEST - (char) 1},
254         new char[] {GREATEST, GREATEST},
255         new char[] {GREATEST, GREATEST, GREATEST});
256 
257     Comparator<char[]> comparator = Chars.lexicographicalComparator();
258     Helpers.testComparator(comparator, ordered);
259   }
260 
261   public void testToArray() {
262     // need explicit type parameter to avoid javac warning!?
263     List<Character> none = Arrays.<Character>asList();
264     assertTrue(Arrays.equals(EMPTY, Chars.toArray(none)));
265 
266     List<Character> one = Arrays.asList((char) 1);
267     assertTrue(Arrays.equals(ARRAY1, Chars.toArray(one)));
268 
269     char[] array = {(char) 0, (char) 1, 'A'};
270 
271     List<Character> three = Arrays.asList((char) 0, (char) 1, 'A');
272     assertTrue(Arrays.equals(array, Chars.toArray(three)));
273 
274     assertTrue(Arrays.equals(array, Chars.toArray(Chars.asList(array))));
275   }
276 
277   public void testToArray_threadSafe() {
278     for (int delta : new int[] { +1, 0, -1 }) {
279       for (int i = 0; i < VALUES.length; i++) {
280         List<Character> list = Chars.asList(VALUES).subList(0, i);
281         Collection<Character> misleadingSize =
282             Helpers.misleadingSizeCollection(delta);
283         misleadingSize.addAll(list);
284         char[] arr = Chars.toArray(misleadingSize);
285         assertEquals(i, arr.length);
286         for (int j = 0; j < i; j++) {
287           assertEquals(VALUES[j], arr[j]);
288         }
289       }
290     }
291   }
292 
293   public void testToArray_withNull() {
294     List<Character> list = Arrays.asList((char) 0, (char) 1, null);
295     try {
296       Chars.toArray(list);
297       fail();
298     } catch (NullPointerException expected) {
299     }
300   }
301 
302   public void testAsList_isAView() {
303     char[] array = {(char) 0, (char) 1};
304     List<Character> list = Chars.asList(array);
305     list.set(0, (char) 2);
306     assertTrue(Arrays.equals(new char[] {(char) 2, (char) 1}, array));
307     array[1] = (char) 3;
308     assertEquals(Arrays.asList((char) 2, (char) 3), list);
309   }
310 
311   public void testAsList_toArray_roundTrip() {
312     char[] array = { (char) 0, (char) 1, (char) 2 };
313     List<Character> list = Chars.asList(array);
314     char[] newArray = Chars.toArray(list);
315 
316     // Make sure it returned a copy
317     list.set(0, (char) 4);
318     assertTrue(Arrays.equals(
319         new char[] { (char) 0, (char) 1, (char) 2 }, newArray));
320     newArray[1] = (char) 5;
321     assertEquals((char) 1, (char) list.get(1));
322   }
323 
324   // This test stems from a real bug found by andrewk
325   public void testAsList_subList_toArray_roundTrip() {
326     char[] array = { (char) 0, (char) 1, (char) 2, (char) 3 };
327     List<Character> list = Chars.asList(array);
328     assertTrue(Arrays.equals(new char[] { (char) 1, (char) 2 },
329         Chars.toArray(list.subList(1, 3))));
330     assertTrue(Arrays.equals(new char[] {},
331         Chars.toArray(list.subList(2, 2))));
332   }
333 
334   public void testAsListEmpty() {
335     assertSame(Collections.emptyList(), Chars.asList(EMPTY));
336   }
337 }
338